﻿using BMSPlatform.CustomClass;
using C5;
using DataManage;
using DataManage.Data;
using DataManage.Enum;
using ServiceLayerManagement;
using ServiceLayerManagement.Tool;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Documents;
using System.Windows.Markup;

namespace BMSPlatform.DeviceCommunication
{
    /// <summary>
    /// 数据队列处理
    /// </summary>
    public class DeviceDataHandle
    {
        #region 公共变量
        private static PageType pageIndex;
        public static PageType PageIndex { get => pageIndex; set { pageIndex = value; PageChanged(); } }
        private static Tuple<SubTermType, int> boardIndex;
        /// <summary>
        /// 从板索引
        /// </summary>
        public static Tuple<SubTermType, int> BoardIndex { get => boardIndex; set { boardIndex = value; BoardIndexChanged(); } }

        
        #endregion
        #region 私有变量
        /// <summary>
        /// 当前指令的下位机应答帧ID
        /// </summary>
        private static uint? lowerCId;
        /// <summary>
        /// 应答数据包总数
        /// </summary>
        private static int? responseDataCount;
        /// <summary>
        /// 应答指令数据段验证
        /// </summary>
        private static byte[] validateArray;
        /// <summary>
        /// 接收应答指令超时线程
        /// <para>发送指令时阻塞线程</para>
        /// <para>发送成功，接收到数据后启动线程</para>
        /// </summary>
        private static AutoResetEvent receivedDataResetManual = new AutoResetEvent(false);

        /// <summary>
        /// 应答数据集合
        /// </summary>
        private static ConcurrentQueue<DataFrames> responseData = new ConcurrentQueue<DataFrames>();
        /// <summary>
        /// 已处理完毕的数据集合
        /// </summary>
        private static List<ProcessedData> processedDatas;
        /// <summary>
        /// 递增数值
        /// </summary>
        private const int addNum = 10000;
        #endregion

        #region 消费队列
        /// <summary>
        /// 获取应答集合
        /// </summary>
        /// <param name="overTime">超时时间</param>
        /// <param name="len">应答数据包总数</param>
        /// <param name="verData">应答帧数据内容</param>
        public static RespResult<List<DataFrames>> GetResponseData(int overTime, int len, DataFrames dataFrames, byte[] verData = null)
        {
            //发送指令
            DeviceConnected.SendData(dataFrames);
            responseDataCount = len;
            GetResponseId(dataFrames.CANId);
            validateArray = verData?.Length > 0 ? verData : null;
            RespResult<List<DataFrames>> respResult = new RespResult<List<DataFrames>>();
            //等待服务器返回数据
            if (validateArray?.Length > 0 && !receivedDataResetManual.WaitOne(overTime))
            {
                respResult.Code = -3;
                respResult.Message = "等待应答数据超时";
                return respResult;
            }

            respResult.Code = 0;
            respResult.Message = "读取应答数据成功";
            if(responseData?.Count > 0)
            {
                respResult.Body = new RespBody<List<DataFrames>>()
                {
                    CommandId = responseData.FirstOrDefault().CANId,
                    Data = new List<DataFrames>(SerializeHelper.DeepCopy(responseData.ToList()))
                };
                QueueClear();
            }

            return respResult;
        }


        /// <summary>
        /// 接收数据队列处理
        /// </summary>
        public static void ReceivedDataQueueHandle()
        {
            bool validate = true;
            DataFrames dataFrames;
            DataFramePointTable dataFramePointTable = new DataFramePointTable();
            while (GlobalData.ReceivedDataQueueResetManual.WaitOne())
            {
                if (GlobalData.ReceviedData.Count > 0)
                {
                    if (GlobalData.ReceviedData.TryDequeue(out dataFrames))
                    {
                        if (responseDataCount != null //应答包数不为空
                            && lowerCId != null && dataFrames.CANId == lowerCId)//应答ID不为空且ID一致
                        {//应答数据处理
                            if (validateArray?.Length > 0)
                            {
                                //应答包验证
                                validate = validateArray.All(p => dataFrames.Data.Contains(p)) ? true : false;
                                #region 
                                //for (int i = 0; i < validateArray.Length; i++)
                                //{
                                //    if (dataFrames.Data[i] != validateArray[i])
                                //    {//应答包验证
                                //        validate = false;
                                //        break;
                                //    }
                                //}
                                #endregion
                            }
                            if (validate)
                            {
                                responseData.Enqueue(dataFrames);
                                if (responseData.Count >= responseDataCount)
                                {
                                    lowerCId = null;
                                    receivedDataResetManual.Set();
                                }
                            }
                            validate = true;
                        }
                        else
                        {//无应答数据处理
                            if (ValidateDataFrame(dataFrames, dataFramePointTable)) ParseFrame(dataFrames);
                        }
                    }
                }
                Thread.Sleep(10);
            }
        }

        /// <summary>
        /// 获取应答ID
        /// </summary>
        /// <param name="upperCId">上位机发出的帧ID</param>
        /// <returns></returns>
        private static void GetResponseId(uint upperCId)
        {
            string strId = upperCId.ToString("X8");

            strId = $"{strId.Substring(0, 4)}" +
                    $"{strId.Substring(strId.Length - 2)}" +
                    $"{strId.Substring(strId.Length - 4, 2)}";

            if (uint.TryParse(strId, System.Globalization.NumberStyles.HexNumber, null, out uint id)) lowerCId = id;
        }
        /// <summary>
        /// 应答数据队列清空
        /// </summary>
        private static void QueueClear()
        {
            while (responseData.TryDequeue(out _)) ;
        }
        #endregion


        #region 数据解析
        /// <summary>
        /// 解析数据帧逻辑
        /// </summary>
        private static void ParseFrame(DataFrames dataFrames)
        {
            //数值
            double dValue;
            int iValue = 0;
            Int64 lValue = 0;
            object obj;
            //临时字节数组
            byte[] tempBytearray = new byte[0];
            ProcessedData processedData = new ProcessedData() { Result = new List<object>()};
            List<Tuple<int, int, byte>> algorithmicRules;
            Tuple<int, int, byte> algorithmicRule;
            List<byte[]> data;
            //获取点表数据
            List<DataFramePointTable> dataFramePointTables = GlobalData.FramePointTable.
                Where(p => (p.CellCount == null && p.CANID == dataFrames.CANId) ||
                      (p.CellCount != null && p.CANID <= dataFrames.CANId && p.EndCANID >= dataFrames.CANId)).ToList();
            if (dataFramePointTables == null && dataFramePointTables.Count <= 0) return;

            foreach(DataFramePointTable dataFramePointTable in dataFramePointTables)
            {
                //获取失败，返回
                if (dataFramePointTable == null) continue;

                #region 解析
                /*
                 * 1.多个字节表示一个数据
                 * 2.一个数据段，多个数据，比如单体电压
                 */
                data = SplitAry(dataFrames.Data, dataFramePointTable);
                foreach (byte[] bytes in data)
                {
                    if (dataFramePointTable.AlgorithmicRules?.Count > 0)
                    {
                        for (int i = 0; i < bytes.Length; i++)
                        {
                            //字节进行指定转换
                            algorithmicRules = dataFramePointTable.AlgorithmicRules.Where(p => p.Item1.Equals(i)).ToList();
                            if (algorithmicRules == null || algorithmicRules.Count <= 0) continue;

                            for (int j = 0; j < algorithmicRules.Count; j++)
                            {
                                algorithmicRule = algorithmicRules[j];
                                switch (algorithmicRule.Item2)
                                {
                                    case 0:
                                        bytes[i] &= algorithmicRule.Item3;
                                        break;
                                    case 1:
                                        bytes[i] <<= algorithmicRule.Item3;
                                        break;
                                    case 2:
                                        bytes[i] >>= algorithmicRule.Item3;
                                        break;
                                }
                            }

                        }
                    }

                    if (!dataFramePointTable.SequentialRules_H) tempBytearray = bytes.Reverse().ToArray();

                    //转换
                    switch (dataFramePointTable.DataLength)
                    {
                        case 1:
                            iValue = tempBytearray[0];
                            break;
                        case 2:
                            iValue = BitConverter.ToUInt16(tempBytearray, 0);
                            break;
                        case 4:
                            iValue = BitConverter.ToInt32(tempBytearray, 0);
                            break;
                        case 8:
                            lValue = BitConverter.ToInt64(tempBytearray, 0);
                            break;
                    }
                    switch (dataFramePointTable.FrameType)
                    {
                        case DataFrameType.Numeric:
                            //单位
                            dValue = (iValue * dataFramePointTable.ScaleFactor) + dataFramePointTable.Offset;
                            //if (dValue < dataFramePointTable.StartValue || dValue > dataFramePointTable.EndValue) dValue = null;
                            processedData.Result.Add(dValue);
                            break;
                        case DataFrameType.Enumeration:
                        case DataFrameType.ResourceDictionary:
                        case DataFrameType.Fault:
                            //若没有则不赋值
                            obj = GetResourceName(dataFramePointTable.ResourceIndex, iValue, lValue);
                            if(obj != null)
                            processedData.Result.Add(obj);

                            break;
                        default:
                            continue;
                    }
                }
                #endregion
            }
            lock(processedDatas)
            {
                if (processedDatas == null) processedDatas = new List<ProcessedData>();
                processedData.CANID = dataFrames.CANId;
                processedData.FrameIndex = (dataFramePointTables.FirstOrDefault().IsFixedFrame ? dataFrames.Data[0] : 0);
                processedData.TimeStamp = dataFrames.DateTimeStamp;
                processedDatas.Add(SerializeHelper.DeepCopy(processedData));
                processedData.Result.Clear();
            }
           

        }

        #endregion

        #region 数据刷新线程
        /// <summary>
        /// 启动数据刷新
        /// </summary>
        public static void PageDataRefresh()
        {
            //待刷新的数据
            List<ProcessedData> updateData = new List<ProcessedData>();
            ProcessedData processedData = new ProcessedData();
            MBMUInfo mBMUInfo = new MBMUInfo()
            {
                PrimaryControlSBMUData = new System.Collections.ObjectModel.ObservableCollection<PrimaryControlSBMUInfo>()
            };
            SecondaryControlSBMUInfo secondaryControlSBMUInfo = new SecondaryControlSBMUInfo()
            {
                VCMUData = new System.Collections.ObjectModel.ObservableCollection<VCMUInfo>(),
                TCMUData = new System.Collections.ObjectModel.ObservableCollection<TCMUInfo>()
            };
            List<DataFramePointTable> pointTableDatas = new List<DataFramePointTable>();
            DataFramePointTable pointTableData = new DataFramePointTable();
            while (GlobalData.ReceivedDataQueueResetManual.WaitOne())
            {
                ConsumptionPagebufferData(mBMUInfo, secondaryControlSBMUInfo, pointTableDatas, pointTableData, updateData, processedData);
                #region 顺序调整
                #endregion
                switch (PageIndex)
                {//根据索引判断刷新mBMUInfo还是secondaryControlSBMUInfo还是子项
                    
                }
                Thread.Sleep(100);
            }  
        }
        /// <summary>
        /// 消费显示缓冲区的数据
        /// </summary>
        private static void ConsumptionPagebufferData(MBMUInfo mBMUInfo, SecondaryControlSBMUInfo secondaryControlSBMUInfo, List<DataFramePointTable> pointTableDatas, DataFramePointTable pointTableData, List<ProcessedData> updateData, ProcessedData processedData)
        {
            int count;
            bool endWait = false;
            ulong startId, endId = 0;

            pointTableDatas = GlobalData.FramePointTable.Where(p => p.BelongPageType.Equals(pageIndex)).ToList();
            if (pointTableDatas == null || pointTableDatas.Count <= 0) return;

            for (int i = 0; i < pointTableDatas.Count; i++)
            {
                pointTableData = pointTableDatas[i];

                #region 验证数据完整
                do
                {
                    if (pointTableData.FrameNum > 1)
                    {//固定ID的多帧
                        for (int z = 1; z <= pointTableData.FrameNum; z++)
                        {
                            if (processedDatas.Count(p => p.CANID == pointTableData.CANID && p.FrameIndex == z) <= 0)
                                break;
                        }
                    }
                    else if (pointTableData.CellCount != null)
                    {//判断缓冲区数据的范围帧是否达到指定数量（数量根据AssignmentIndex字段判断），若没有则等待do while，若超时一次则继续往下，能取出多少是多少
                        count = processedDatas.DistinctBy(p => p.CANID).Count(q => q.CANID >= pointTableData.CANID && q.CANID <= pointTableData.EndCANID);
                        if (count >= pointTableData.CellCount)
                        {
                            endId = pointTableData.EndCANID;
                            break;
                        }
                        else
                        {
                            endId = pointTableData.CANID + (ulong)(count * addNum);
                        }
                    }
                    else
                    {//常规
                        if (processedDatas.Count(p => p.CANID == pointTableData.CANID) > 0)
                        {
                            endWait = !endWait;//直接退出do_while
                            break;
                        }
                    }
                    if (!endWait) Thread.Sleep(pointTableData.TransmissionCycle);

                    endWait = !endWait;

                } while (endWait);

                #endregion

                #region 获取值
                startId = pointTableData.CANID;
                do
                {
                    for(int m = 1; m <= pointTableData.FrameNum; m++)
                    {//遍历同ID多帧
                        processedData = processedDatas.Where(p => p.CANID == startId && p.FrameIndex == m).OrderBy(p => p.TimeStamp).FirstOrDefault();
                        if (processedData != null)
                         updateData.Add(SerializeHelper.DeepCopy(processedData));
                    }
                    //遍历不同ID的多帧
                    startId += addNum;
                } while (pointTableData.CANID > endId);
                #endregion

                lock (processedDatas)
                {
                    processedDatas.RemoveAll(p => updateData.Count(q => q.Equals(p.TimeStamp)) > 0);
                }

                if (updateData.Count <= 0) continue;

                SetFieldValue(pointTableData.AssignmentIndex, updateData, mBMUInfo, secondaryControlSBMUInfo);
                updateData.Clear();
            }
        }
        #endregion

        /// <summary>
        /// 枚举|资源字段
        /// </summary>
        /// <param name="resourceIndex">资源索引</param>
        /// <param name="resourceKey">资源Key值</param>
        /// <returns>返回相应名称</returns>
        private static object GetResourceName(ResourceType resourceIndex, int resourceKey, Int64 lresourceKey)
        {//判断字典或者枚举值是否存在
            //非故障信息
            //switch(resourceIndex)
            //{
            //    case 1:
            //        if(Collection.SystemRunStateDescription.ContainsKey(resourceKey))
            //            return Collection.SystemRunStateDescription[resourceKey];

            //        break;
            //    case 2:
            //        if (Collection.ChgDchStateDescription.ContainsKey(resourceKey))
            //            return Collection.ChgDchStateDescription[resourceKey];

            //        break;
            //    case 3:
            //        if (Collection.SystemFaultStateDescription.ContainsKey(resourceKey))
            //            return Collection.SystemFaultStateDescription[resourceKey];
            //        break;
            //    case 4:
            //        if (Collection.RelayStatusDescription.ContainsKey(resourceKey))
            //            return Collection.RelayStatusDescription[resourceKey];
            //        break;
            //    case 5:
            //        if (Collection.SystemCtlCmdStateDescription.ContainsKey(resourceKey))
            //            return Collection.SystemCtlCmdStateDescription[resourceKey];
            //        break;
            //    case 6:
            //        if (Collection.CellBalancedDescription.ContainsKey(resourceKey))
            //            return Collection.CellBalancedDescription[resourceKey];
            //        break;
            //    case 7:
            //        if (Collection.WakeUpModeDescription.ContainsKey(resourceKey))
            //            return Collection.WakeUpModeDescription[resourceKey];
            //        break;
            //    case 8:
            //        if (Collection.PowerStateDescription.ContainsKey(resourceKey))
            //            return Collection.PowerStateDescription[resourceKey];
            //        break;
            //    case 9:
            //        if (Collection.DOControlStateDescription.ContainsKey(resourceKey))
            //            return Collection.DOControlStateDescription[resourceKey];
            //        break;
            //    case 10:
            //        if (Collection.DIControlStateDescription.ContainsKey(resourceKey))
            //            return Collection.DIControlStateDescription[resourceKey];
            //        break;
            //    case 11:
            //        if (Collection.AFEBalanceStateDescription.ContainsKey(resourceKey))
            //            return Collection.AFEBalanceStateDescription[resourceKey];
            //        break;
            //    case 12:
            //        if (Collection.ActivationSignal.ContainsKey(lresourceKey))
            //            return Collection.ActivationSignal[lresourceKey];
            //        break;
            //}

            //if(resourceIndex >= 13 && resourceIndex <= 46)
            //{//故障信息
            //    CustomResource customResource = GlobalData.FaultInfo.CustomResources.FirstOrDefault(p => p.ResourceIndex.Equals(resourceIndex));

            //    if (customResource == null) return string.Empty;

            //    FaultInfo faultInfo = customResource.ResourceInfo.FirstOrDefault(p => p.FaultIndex.Equals(resourceKey));
            //    if (faultInfo != null) return faultInfo.Description;
            //}
            return null;
        }

        private static void BoardIndexChanged()
        {
            GlobalData.ReceivedDataQueueResetManual.Reset();
            string str;
            ulong u;
            processedDatas.Clear();
            if (boardIndex != null)
            {//修改源地址
                List<DataFramePointTable> dataFramePointTables = GlobalData.FramePointTable.Where(p => p.SubTerm == boardIndex.Item1 && !p.IsFixedFrame).ToList();
                foreach(DataFramePointTable dataFramePointTable in dataFramePointTables)
                {
                    str = dataFramePointTable.CANID.ToString("X8");
                    str = $"{str.Substring(0, str.Length - 2)}{pageIndex.ToString("X2")}";
                    if(ulong.TryParse(str, System.Globalization.NumberStyles.HexNumber, null, out u))
                        dataFramePointTable.CANID = u;
                }
            }
            GlobalData.ReceivedDataQueueResetManual.Set();
        }
        private static void PageChanged()
        {
            GlobalData.ReceivedDataQueueResetManual.Reset();
            //赋值为NULL后，使其不再被引用。这将使对象成为垃圾数据，由垃圾回收器处理
            //避免内存泄漏风险
            processedDatas.Clear();
            GlobalData.ReceivedDataQueueResetManual.Set();
        }
        /// <summary>
        /// 验证数据帧是否是当前需要刷新的帧数据
        /// </summary>
        private static bool ValidateDataFrame(DataFrames dataFrame, DataFramePointTable dataFramePointTable)
        {
            if (dataFrame.Data == null || dataFrame.Data.Length <= 0) return false;

            //固定帧
            dataFramePointTable = GlobalData.FramePointTable.FirstOrDefault(p => p.CellCount == null && p.CANID.Equals(dataFrame.CANId));
            if (dataFramePointTable == null)
            {//范围帧
                dataFramePointTable = GlobalData.FramePointTable.FirstOrDefault(p => p.CellCount != null && p.CANID <= dataFrame.CANId && p.EndCANID >= dataFrame.CANId);

                if(dataFramePointTable == null) return false;
            }
            //是否属于当前页面
            if(PageIndex != dataFramePointTable.BelongPageType) return false;

            return true;
        }

        /// <summary>
        /// 将一个数组按固定大小拆分为数组
        /// </summary>
        private static List<byte[]> SplitAry(byte[] ary, DataFramePointTable dataFramePointTable)
        {
            byte[] bytes;
            List<byte[]> subAryList = new List<byte[]>();
            if (dataFramePointTable.CellCount == null)
            {
                bytes = ary.Skip(dataFramePointTable.StartIndex).Take(dataFramePointTable.DataLength).ToArray();
                subAryList.Add(bytes);
                return subAryList;
            }

            int count = ary.Length % dataFramePointTable.DataLength == 0 ? ary.Length / dataFramePointTable.DataLength : ary.Length / dataFramePointTable.DataLength + 1;
            for (int i = 0; i < count; i++)
            {
                int index = i * dataFramePointTable.DataLength;
                byte[] subary = ary.Skip(index).Take(dataFramePointTable.DataLength).ToArray();
                subAryList.Add(subary);
            }
            return subAryList;
        }

        /// <summary>
        /// 字段赋值
        /// </summary>
        private static void SetFieldValue(VariableType assignmentIndex, List<ProcessedData> processedData, MBMUInfo mBMUInfo, SecondaryControlSBMUInfo secondaryControlSBMUInfo)
        {
            #region 
            //switch (pointTableData.AssignmentIndex)
            //{
            //    #region MBMU
            //    case 0:
            //        mBMUInfo.BmsVoltage = data.FirstOrDefault().ToDouble();
            //        break;
            //    case 1:
            //        mBMUInfo.BmsCurrent = data.FirstOrDefault().ToDouble();
            //        break;
            //    case 2:
            //        mBMUInfo.BmsPower = data.FirstOrDefault().ToDouble();
            //        break;
            //    case 3:
            //        mBMUInfo.BmsChgDchEfficiency = data.FirstOrDefault().ToDouble();
            //        break;
            //    case 4:
            //        mBMUInfo.SystemRunState = data.FirstOrDefault().ToString();
            //        break;
            //    case 5:
            //        mBMUInfo.ChgDchState = data.FirstOrDefault().ToString();
            //        break;
            //    case 6:
            //        mBMUInfo.SystemFaultState = data.FirstOrDefault().ToString();
            //        break;
            //    case 7:
            //        mBMUInfo.MuteEnable = data.FirstOrDefault().ToString();
            //        break;
            //    case 8:
            //        mBMUInfo.SingleClusterMaintenanceEnable = data.FirstOrDefault().ToString();
            //        break;
            //    case 9:
            //        mBMUInfo.SOC = data.FirstOrDefault().ToDouble();
            //        break;
            //    case 10:
            //        mBMUInfo.SOE = data.FirstOrDefault().ToDouble();
            //        break;
            //    case 11:
            //        mBMUInfo.SOH = data.FirstOrDefault().ToDouble();
            //        break;
            //    case 12:
            //        mBMUInfo.SOR = data.FirstOrDefault().ToDouble();
            //        break;
            //    case 13://干节点1
            //    case 14://干节点2
            //    case 15://干节点3
            //    case 16://干节点4
            //    case 17://干节点5
            //    case 18://正极高边继电器
            //    case 19://负极高边继电器
            //    case 20://预充继电器
            //    case 21://充电正继电器
            //    case 22://充电负继电器
            //    case 23://加热继电器
            //    case 24://正极低边继电器
            //    case 25://负极低边继电器
            //        if(Enum.TryParse(data.FirstOrDefault().ToString(), out RelayStatus result))
            //        mBMUInfo.RelayInfo.Add(pointTableData.Name, result);

            //        break;
            //    case 26://RTC
            //        break;
            //    case 27://硬件版本
            //        break;
            //    case 28://软件版本
            //        break;
            //    case 29://最高电芯电压
            //    case 30://最高电芯电压簇号
            //    case 31://最低电芯电压
            //    case 32://最低电芯电压簇号
            //    case 33://电芯压差
            //    case 34://最高电池温度
            //    case 35://最高电池温度簇号
            //    case 36://最低电池温度
            //    case 37://最低电池温度簇号
            //    case 38://电池温差
            //        mBMUInfo.BatteryCellData.Add(pointTableData.Name, data.FirstOrDefault().ToDouble());
            //        break;
            //    case 39://外总压
            //    case 40://负极总压
            //    case 41://最大允许充电电流
            //    case 42://最大允许放电电流
            //    case 43://最大允许充电功率
            //    case 44://最大允许放电功率
            //    case 45://最大电池簇电流
            //    case 46://最大电池簇电流簇号
            //    case 47://最小电池簇电流
            //    case 48://最小电池簇电流簇号
            //    case 49://簇间电流极差
            //    case 50://可用SOC
            //    case 51://当前可充容量
            //    case 52://当前可充电量
            //    case 53://当前可放容量
            //    case 54://当前可放电量
            //    case 55://正端绝缘电阻
            //    case 56://负端绝缘电阻
            //    case 57://充电插座1CC2阻值
            //    case 58://充电插座1CC2阻值
            //    case 59://快充口01插座正极温度
            //    case 60://快充口01插座负极温度
            //    case 61://快充口02插座正极温度
            //    case 62://快充口02插座负极温度
            //    case 63://环境温度1
            //    case 64://环境温度2
            //    case 65://DI状态1
            //    case 66://DI状态2
            //    case 67://DI状态3
            //    case 68://DI状态4
            //    case 69://DI状态5
            //    case 70://DI状态6
            //    case 71://DI状态7
            //    case 72://DI状态8
            //        mBMUInfo.OtherInfo.Add(pointTableData.Name, data.FirstOrDefault().ToDouble());
            //        break;
            //    #endregion

            //    #region 从控SBMU
            //    case 73:

            //        break;
            //    #endregion
            //    #region 主控SBMU
            //    case 73:

            //        break;
            //    #endregion
            //    #region VCMU
            //    case 73:

            //        break;
            //    #endregion
            //    #region TCMU
            //    case 73:

            //        break;
            //        #endregion
            //}
            #endregion
        }
    }
}
